import json


def sum_nums(low: int, high: int):
    """
    while实现从low到high的整数累加和
    :param low: 较小整数
    :param high: 较大整数
    :return: 累加和
    """
    if high < low:
        print("error")
        return
    sum_num = 0
    while low <= high:
        sum_num += low
        low += 1
    return sum_num


def remove_duplicate_element(initial_list: list):
    """
    实现一个可以移除list中重复元素的算法
    :param initial_list:待处理初始列表
    :return:已去重列表
    """
    immutable_set = set()  # 不可变对象存放集合
    mutable_set = set()  # 可变对象存放集合
    for item in initial_list:
        try:  # 测试列表元素是否可变，分别进行去重
            hash(item)
            immutable_set.add(item)
        except TypeError:
            mutable_set.add(json.dumps(item))  # 使用json封装列表可变数据为字符串以去重
    unique_list = [json.loads(element) for element in mutable_set]  # 使用json加载还原列表数据
    unique_list.extend(list(immutable_set))  # 合并两个集合
    return unique_list


def binary_search_l(sorted_array, x):
    """
    实现二分搜索查找有序数组中满足sorted_array[i]>=x的索引i
    :param sorted_array: 有序数组
    :param x: 指定数字
    :return: 大于指定数字x的索引i
    """
    left, right = 0, len(sorted_array) - 1
    if sorted_array[right] < x:  # 如果指定数字大于有序数组最大值，直接返回-1，表示没有满足要求的索引
        return -1
    while left <= right:  # 二分搜索查找满足要求的索引i
        medium = (left + right) // 2
        if sorted_array[medium] >= x:
            return medium
        else:
            left = medium


if __name__ == '__main__':
    # 来源详见程振波算法设计与分析(Python),P25,e.g 2-3(a)
    # 测试用例
    low_int, high_int = 1, 12
    print("自己实现求和为:{}".format(sum_nums(low_int, high_int)))
    print("系统函数实现求和为:{}".format(sum(range(low_int, high_int + 1))))

    # 来源详见程振波算法设计与分析(Python),P25,e.g 2-3(c)
    # 测试用例
    a = ["hello"]
    i_list = [1, [1], 1, "ac", [1], "ac", 6.8,
              {"1": 2}, 6.8, {"1": 2}, 0xffad,
              0o67, 0b100101, 2.3e-10, 'albert', """darren""", (1, ""), 0xffad,
              0o67, 0b100101, 2.3e-10, 'albert', """darren""", (1, ""), a, a]
    print("移除重复(任意数据类型)元素后的列表为:{}".format(remove_duplicate_element(i_list)))
    # 来源详见程振波算法设计与分析(Python),P25,e.g 2-4(a)
    A = [0, 1, 1, 2, 3, 3, 3, 3, 4, 5, 5, 7, 7, 7]
    print("二分搜索索引为:{}".format(binary_search_l(A, 3)))
    print("小于最小值的二分搜索索引为:{}".format(binary_search_l(A, -10)))
    print("大于最大值的二分搜索索引为:{}".format(binary_search_l(A, 33)))
